package com.solution.wx.share.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Lists;
import com.solution.common.dao.BaseDao;
import com.solution.common.exception.BizException;
import com.solution.common.page.PageBean;
import com.solution.common.page.PageParam;
import com.solution.common.redis.RedisCacheClient;
import com.solution.common.service.impl.BaseServiceImpl;
import com.solution.common.utils.DateUtils_add;
import com.solution.wx.share.constants.ShareConstants.SHARE_TYPE;
import com.solution.wx.share.dao.ShareInfoDao;
import com.solution.wx.share.dao.ShareInteractionCountDao;
import com.solution.wx.share.dao.ShareProductStatisticsDao;
import com.solution.wx.share.entity.ShareInfoEntity;
import com.solution.wx.share.entity.ShareInteractionCountEntity;
import com.solution.wx.share.entity.ShareProductStatisticsEntity;
import com.solution.wx.share.service.ShareInfoService;

/**
 * 用户分享信息service层实现
 * @author xkl
 * @date 2018年5月4日 下午4:42:31
 */
@Service
public class ShareInfoServiceImpl extends BaseServiceImpl<ShareInfoEntity> implements ShareInfoService {
	private static final Logger logger = LoggerFactory.getLogger(ShareInfoServiceImpl.class); 
	@Autowired
	private ShareInfoDao shareInfoDao;
	
	@Autowired
	private ShareInteractionCountDao shareInteractionCountDao;
	
	@Autowired
	private ShareProductStatisticsDao shareProductStatisticsDao;
	
	@Autowired
	RedisCacheClient redisCacheClient;
	
	/**
	 * 分享信息点赞数量信息
	 * 点赞数、评论数、收藏数、分享数、浏览数(PV统计)、注册用户、浏览数(UV统计)
	 */
	private static final String SHARE_INTERACTION = "SHARE_INTERACTION_";
	private static final String LIKE_QUANTITY = "LIKE_QUANTITY";
	private static final String COMMENT_QUANTITY = "COMMENT_QUANTITY";
	private static final String FAVORITE_QUANTITY = "FAVORITE_QUANTITY";
	private static final String SHARE_QUANTITY = "SHARE_QUANTITY";
	private static final String VIEW_QUANTITY = "VIEW_QUANTITY";
	private static final String REGISTER_QUANTITY = "REGISTER_QUANTITY";
	private static final String UV_VIEW_QUANTITY = "UV_VIEW_QUANTITY";
	
	/**
	 * 分享信息变化的分享
	 */
	private static final String SHARE_INTERACTION_CHANGE = "SHARE_INTERACTION_CHANGE";
	
	/**
	 * 用户已点赞的分享信息
	 * 用户已收藏的分享信息
	 * 
	 */
	private static final String USER_LIKE_SHARE = "USER_LIKE_SHARE_";
	private static final String USER_FAVORITE_SHARE = "USER_FAVORITE_SHARE_";
	
	/**
	 * 分享信息查看数(UV统计)
	 */
	private static final String SHARE_UV_VIEW = "SHARE_UV_VIEW_";
	
	/**
	 * 每日分享
	 * 分享数、pv浏览数、uv浏览数、用户注册数、UV用户浏览记录
	 */
	private static final String DAILY_SHARE_QUANTITY = "DAILY_SHARE_QUANTITY";
	private static final String DAILY_SHARE_PV_VIEW = "DAILY_SHARE_PV_VIEW";
	private static final String DAILY_SHARE_UV_VIEW = "DAILY_SHARE_UV_VIEW";
	private static final String DAILY_SHARE_REGISTER = "DAILY_SHARE_REGISTER";
	private static final String DAILY_SHARE_UV_VIEW_USER = "DAILY_SHARE_UV_VIEW_USER";
	
	/**
	 * 邀请注册
	 */
	private static final String INVITE = "INVITE_";
	
	@Override
	protected BaseDao<ShareInfoEntity> getDao() {
		return this.shareInfoDao;
	}
	
	/**
	 * 获取潮品社区分页列表
	 * @param pageParam
	 * @param param
	 * @return
	 * @author xkl
	 * @date 2018年5月4日 下午4:42:41
	 */
	@Override
	public PageBean listShareInfoPage(PageParam pageParam, Map<String, Object> param) {
		PageBean pageBean = shareInfoDao.listPage(pageParam, param);
		for (int i = 0; i < pageBean.getRecordList().size(); i++) {
			ShareInfoEntity entity = (ShareInfoEntity)pageBean.getRecordList().get(i);
			//获取redis中的点赞数
			Long likeQuantity = redisCacheClient.getHashValue(SHARE_INTERACTION + entity.getId(), LIKE_QUANTITY);
			entity.setLikeQuantity(likeQuantity);
		}
		return pageBean;
	}

	/**
	 * 检查用户是否对分享信息点赞
	 * @param pageBean
	 * @param customerId
	 * @return
	 * @author xkl
	 * @date 2018年5月5日 下午4:23:05
	 */
	@Override
	public Long isUserLike(Long shareId, Long customerId) {
		return redisCacheClient.getHashValue(USER_LIKE_SHARE + customerId, shareId.toString());
	}

	/**
	 * 检查用户是否对分享信息收藏
	 * @param pageBean
	 * @param customerId
	 * @return
	 * @author xkl
	 * @date 2018年5月5日 下午4:23:05
	 */
	@Override
	public Long isUserFavorite(Long shareId, Long customerId) {
		return redisCacheClient.getHashValue(USER_FAVORITE_SHARE + customerId, shareId.toString());
	}

	/**
	 * 分享内容点赞
	 * @param shareId
	 * @param customerId
	 * @return
	 * @author xkl
	 * @date 2018年5月5日 下午4:31:30
	 */
	@Override
	public Long doShareInfoLike(Long shareId, Long customerId) {
		//记录分享信息变化
		redisCacheClient.doHashIncrby(SHARE_INTERACTION_CHANGE, shareId.toString());
		//分享内容赞数+1
		redisCacheClient.doHashIncrby(SHARE_INTERACTION + shareId, LIKE_QUANTITY);
		//记录用户点赞
		return redisCacheClient.doHashIncrby(USER_LIKE_SHARE + customerId, shareId.toString());
	}

	/**
	 * 分享内容评论
	 * 评论数+1
	 * @param shareId
	 * @return
	 * @author xkl
	 * @date 2018年5月8日 下午2:46:35
	 */
	@Override
	public Long doShareInfoComment(Long shareId) {
		//记录分享信息变化
		redisCacheClient.doHashIncrby(SHARE_INTERACTION_CHANGE, shareId.toString());
		//分享内容评论+1
		return redisCacheClient.doHashIncrby(SHARE_INTERACTION + shareId, COMMENT_QUANTITY);
	}

	/**
	 * 分享内容收藏
	 * 记录用户收藏信息并对内容收藏数+1
	 * @param shareId
	 * @param customerId
	 * @return
	 * @author xkl
	 * @date 2018年5月8日 下午2:47:15
	 */
	@Override
	public Long doShareInfoFavorite(Long shareId, Long customerId) {
		//持久化至数据库
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("shareId", shareId);
		paramMap.put("customerId", customerId);
		Long id = shareInfoDao.insertFavorite(paramMap);
		//记录分享信息变化
		redisCacheClient.doHashIncrby(SHARE_INTERACTION_CHANGE, shareId.toString());
		//分享内容收藏+1
		redisCacheClient.doHashIncrby(SHARE_INTERACTION + shareId, FAVORITE_QUANTITY);
		//记录用户收藏
		redisCacheClient.doHashIncrby(USER_FAVORITE_SHARE + customerId, shareId.toString());
		return id;
	}

	/**
	 * 分享内容取消收藏
	 * @param shareId
	 * @param customerId
	 * @return
	 * @author xkl
	 * @date 2018年6月12日 上午10:04:24
	 */
	@Override
	public int removeShareInfoFavorite(Long shareId, Long customerId) {
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("shareId", shareId);
		paramMap.put("customerId", customerId);
		int count = shareInfoDao.removeFavorite(paramMap);
		if (count > 0) {
			//记录分享信息变化
			redisCacheClient.doHashIncrby(SHARE_INTERACTION_CHANGE, shareId.toString());
			//分享内容收藏-1
			redisCacheClient.doHashIncrby(SHARE_INTERACTION + shareId, FAVORITE_QUANTITY, -1);
			//移除用户收藏
			redisCacheClient.removeHashKeys(USER_FAVORITE_SHARE + customerId, Lists.newArrayList(new String[]{shareId.toString()}));
		}
		return count;
	}

	/**
	 * 分享内容分享
	 * 分享数+1
	 * @param shareId
	 * @param customerId
	 * @return
	 * @author xkl
	 * @date 2018年5月8日 下午2:48:21
	 */
	@Override
	public Long doShareInfoShared(Long shareId) {
		//记录分享信息变化
		redisCacheClient.doHashIncrby(SHARE_INTERACTION_CHANGE, shareId.toString());
		//分享内容分享+1
		return redisCacheClient.doHashIncrby(SHARE_INTERACTION + shareId, SHARE_QUANTITY);
	}
	
	/**
	 * 分享内容浏览次数+1
	 * @param shareId
	 * @return
	 * @author xkl
	 * @date 2018年5月17日 下午2:32:40
	 */
	@Override
	public Long doShareInfoView(Long shareId){
		//记录分享信息变化
		redisCacheClient.doHashIncrby(SHARE_INTERACTION_CHANGE, shareId.toString());
		//分享内容浏览数+1
		return redisCacheClient.doHashIncrby(SHARE_INTERACTION + shareId, VIEW_QUANTITY);
	}
	
	/**
	 * 分享内容引导注册次数+1
	 * @param shareId
	 * @return
	 * @author xkl
	 * @date 2018年5月22日 下午5:58:43
	 */
	@Override
	public Long doShareInfoRegister(Long shareId){
		//记录分享信息变化
		redisCacheClient.doHashIncrby(SHARE_INTERACTION_CHANGE, shareId.toString());
		//分享内容引导注册数+1
		return redisCacheClient.doHashIncrby(SHARE_INTERACTION + shareId, REGISTER_QUANTITY);
	}

	/**
	 * 获取用户分享信息
	 * @param shareId
	 * @return
	 * @author xkl
	 * @date 2018年5月7日 下午5:09:41
	 */
	@Override
	public ShareInfoEntity getShareInfoById(Long shareId) {
		ShareInfoEntity shareInfo = shareInfoDao.getById(shareId);
		if (null == shareInfo) {
			return null;
		}
		//获取redis中的点赞数、评论数、分享数、收藏数
		Long likeQuantity = redisCacheClient.getHashValue(SHARE_INTERACTION + shareId, LIKE_QUANTITY);
		Long commentQuantity = redisCacheClient.getHashValue(SHARE_INTERACTION + shareId, COMMENT_QUANTITY);
		Long shareQuantity = redisCacheClient.getHashValue(SHARE_INTERACTION + shareId, SHARE_QUANTITY);
		Long favoriteQuantity = redisCacheClient.getHashValue(SHARE_INTERACTION + shareId, FAVORITE_QUANTITY);
		Long viewQuantity = redisCacheClient.getHashValue(SHARE_INTERACTION + shareId, VIEW_QUANTITY);
		Long registerQuantity = redisCacheClient.getHashValue(SHARE_INTERACTION + shareId, REGISTER_QUANTITY);
		Long uvViewQuantity = redisCacheClient.getHashValue(SHARE_INTERACTION + shareId, UV_VIEW_QUANTITY);
		shareInfo.setLikeQuantity(likeQuantity);
		shareInfo.setCommentQuantity(commentQuantity);
		shareInfo.setShareQuantity(shareQuantity);
		shareInfo.setFavoriteQuantity(favoriteQuantity);
		shareInfo.setViewQuantity(viewQuantity);
		shareInfo.setRegisterQuantity(registerQuantity);
		shareInfo.setUvViewQuantity(uvViewQuantity);
		return shareInfo;
	}

	/**
	 * 根据uuid获取分享信息
	 * @param uuid
	 * @return
	 * @author xkl
	 * @date 2018年5月11日 上午9:57:55
	 */
	@Override
	public ShareInfoEntity getShareInfoByUUID(String uuid) {
		ShareInfoEntity shareInfo = shareInfoDao.getShareInfoByUUID(uuid);
		if (null == shareInfo) {
			return null;
		}
		//获取redis中的点赞数、评论数、分享数、收藏数、浏览数、注册数
		Long likeQuantity = redisCacheClient.getHashValue(SHARE_INTERACTION + shareInfo.getId(), LIKE_QUANTITY);
		Long commentQuantity = redisCacheClient.getHashValue(SHARE_INTERACTION + shareInfo.getId(), COMMENT_QUANTITY);
		Long shareQuantity = redisCacheClient.getHashValue(SHARE_INTERACTION + shareInfo.getId(), SHARE_QUANTITY);
		Long favoriteQuantity = redisCacheClient.getHashValue(SHARE_INTERACTION + shareInfo.getId(), FAVORITE_QUANTITY);
		Long viewQuantity = redisCacheClient.getHashValue(SHARE_INTERACTION + shareInfo.getId(), VIEW_QUANTITY);
		Long registerQuantity = redisCacheClient.getHashValue(SHARE_INTERACTION + shareInfo.getId(), REGISTER_QUANTITY);
		Long uvViewQuantity = redisCacheClient.getHashValue(SHARE_INTERACTION + shareInfo.getId(), UV_VIEW_QUANTITY);
		shareInfo.setLikeQuantity(likeQuantity);
		shareInfo.setCommentQuantity(commentQuantity);
		shareInfo.setShareQuantity(shareQuantity);
		shareInfo.setFavoriteQuantity(favoriteQuantity);
		shareInfo.setViewQuantity(viewQuantity);
		shareInfo.setRegisterQuantity(registerQuantity);
		shareInfo.setUvViewQuantity(uvViewQuantity);
		return shareInfo;
	}

	/**
	 * 保存分享信息(同时初始化交互数据)
	 * @param entity
	 * @return
	 * @author xkl
	 * @date 2018年5月11日 上午11:28:40
	 */
	@Override
	@Transactional
	public Long saveShareInfo(ShareInfoEntity entity) {
		Long shareId = shareInfoDao.insert(entity);
		entity.setId(shareId);
		//初始化分享交互统计数据
		ShareInteractionCountEntity interactionEntity = initShareInteraction(entity);
		shareInteractionCountDao.insert(interactionEntity);
		//初始化商品统计数据(若存在则不需要初始化)
		int count = shareProductStatisticsDao.isExistsProductStatistics(entity.getSharedProductId());
		if (count == 0 && SHARE_TYPE.PRODUCT.getCode().equals(entity.getShareType())) {
			ShareProductStatisticsEntity statisticsEntity = initShareStatistics(entity);
			shareProductStatisticsDao.insert(statisticsEntity);
		}
		return shareId;
	}

	/**
	 * 批量保存商品信息
	 * @param shareInfoList
	 * @return
	 * @author xkl
	 * @date 2018年6月12日 下午6:50:09
	 */
	@Override
	@Transactional
	public int saveShareInfo(List<ShareInfoEntity> shareInfoList) {
		List<ShareInteractionCountEntity> interactionList = new ArrayList<ShareInteractionCountEntity>();
		List<ShareProductStatisticsEntity> statisticsList = new ArrayList<ShareProductStatisticsEntity>();
		for (ShareInfoEntity entity : shareInfoList) {
			Long shareId = shareInfoDao.insert(entity);
			entity.setId(shareId);
			//初始化分享交互统计数据
			ShareInteractionCountEntity interactionEntity = initShareInteraction(entity);
			interactionList.add(interactionEntity);
			//初始化商品统计数据(若存在则不需要初始化)
			int count = shareProductStatisticsDao.isExistsProductStatistics(entity.getSharedProductId());
			if (count == 0 && SHARE_TYPE.PRODUCT.getCode().equals(entity.getShareType())) {
				ShareProductStatisticsEntity statisticsEntity = initShareStatistics(entity);
				statisticsList.add(statisticsEntity);
			}
		}
		shareInteractionCountDao.insert(interactionList);
		shareProductStatisticsDao.insert(statisticsList);
		return 1;
	}

	/**
	 * 获取已改变的分享信息key
	 * @return
	 * @author xkl
	 * @date 2018年5月17日 下午3:21:07
	 */
	@Override
	public List<String> listChangeShareInfo() {
		Set<String> keySet = redisCacheClient.getHashKeys(SHARE_INTERACTION_CHANGE);
		List<String> keyList = Lists.newArrayList(keySet);
		return keyList;
	}

	/**
	 * 查询我的分享列表
	 * @param pageParam
	 * @param param
	 * @return
	 * @author xkl
	 * @date 2018年5月17日 下午8:06:51
	 */
	@Override
	public PageBean listMySharePage(PageParam pageParam, Map<String, Object> param) {
		return shareInfoDao.listMySharePage(pageParam, param);
	}

	/**
	 * 获取分享途径的已完成销售订单统计
	 * @param paramMap
	 * @return
	 * @author xkl
	 * @date 2018年5月19日 下午1:33:13
	 */
	@Override
	public Map<Long, Map<String, Object>> listShareOrderInfo(Map<String, Object> paramMap) {
		return shareInfoDao.listShareOrderInfo(paramMap);
	}

	/**
	 * 从redis中读取分享的用户交互数据信息
	 * @param shareId
	 * @return
	 * @author xkl
	 * @date 2018年5月22日 下午6:04:01
	 */
	@Override
	public ShareInfoEntity getShareInteraction(String shareId) {
		ShareInfoEntity shareInfo = new ShareInfoEntity();
		//获取redis中的点赞数、评论数、分享数、收藏数、浏览数、注册数
		Long likeQuantity = redisCacheClient.getHashValue(SHARE_INTERACTION + shareId, LIKE_QUANTITY);
		Long commentQuantity = redisCacheClient.getHashValue(SHARE_INTERACTION + shareId, COMMENT_QUANTITY);
		Long shareQuantity = redisCacheClient.getHashValue(SHARE_INTERACTION + shareId, SHARE_QUANTITY);
		Long favoriteQuantity = redisCacheClient.getHashValue(SHARE_INTERACTION + shareId, FAVORITE_QUANTITY);
		Long viewQuantity = redisCacheClient.getHashValue(SHARE_INTERACTION + shareId, VIEW_QUANTITY);
		Long registerQuantity = redisCacheClient.getHashValue(SHARE_INTERACTION + shareId, REGISTER_QUANTITY);
		Long uvViewQuantity = redisCacheClient.getHashValue(SHARE_INTERACTION + shareId, UV_VIEW_QUANTITY);
		shareInfo.setLikeQuantity(likeQuantity);
		shareInfo.setCommentQuantity(commentQuantity);
		shareInfo.setShareQuantity(shareQuantity);
		shareInfo.setFavoriteQuantity(favoriteQuantity);
		shareInfo.setViewQuantity(viewQuantity);
		shareInfo.setRegisterQuantity(registerQuantity);
		shareInfo.setUvViewQuantity(uvViewQuantity);
		return shareInfo;
	}

	/**
	 * 移除redis内数据改变列表内的数据
	 * @param shareidList
	 * @return
	 * @author xkl
	 * @date 2018年5月23日 下午4:32:40
	 */
	@Override
	public Long removeShareInteractionChange(List<String> shareIdList) {
		return redisCacheClient.removeHashKeys(SHARE_INTERACTION_CHANGE, shareIdList);
	}

	/**
	 * 分享信息PV、UV统计
	 * @param shareId
	 * @param customer
	 * @return
	 * @author xkl
	 * @date 2018年6月2日 下午3:16:27
	 */
	@Override
	public Long doShareInfoPVUV(Long shareId, String customer) {
		//记录分享信息变化
		redisCacheClient.doHashIncrby(SHARE_INTERACTION_CHANGE, shareId.toString());
		//分享内容浏览数+1(PV)
		redisCacheClient.doHashIncrby(SHARE_INTERACTION + shareId, VIEW_QUANTITY);
		
		//检查用户是否查看过该分享信息(UV)
		Long isUserView = redisCacheClient.getHashValue(SHARE_UV_VIEW + shareId, customer);
		if (isUserView <= 0) {
			//分享内容UV+1
			redisCacheClient.doHashIncrby(SHARE_INTERACTION + shareId, UV_VIEW_QUANTITY);
			//记录查看的用户
			return redisCacheClient.doHashIncrby(SHARE_UV_VIEW + shareId, customer);
		}
		return 1L;
	}

	/**
	 * 保存分享商品订单记录
	 * @param paramMap
	 * @return
	 * @author xkl
	 * @date 2018年6月4日 下午7:13:46
	 */
	@Override
	public int saveShareOrder(Map<String, Object> paramMap) {
		return shareInfoDao.saveShareOrder(paramMap);
	}

	/**
	 * 分享信息与商品销售统计
	 * @return
	 * @author xkl
	 * @date 2018年6月4日 下午7:13:49
	 */
	@Override
	@Transactional
	public int updateShareOrderStatistics() {
		try {
			//获取前一天时间(昨日00:00至23:59时间参数)
			Calendar cal = Calendar.getInstance();
			cal.setTime(new Date());
			cal.add(Calendar.DATE, -1);
			Map<String, Object> paramMap = new HashMap<String, Object>();
			paramMap.put("stratDate", DateUtils_add.getDayStart(cal.getTime()));
			paramMap.put("endDate", DateUtils_add.getDayEnd(cal.getTime()));
			//同步昨日分享信息订单数据至shareOrder表
			shareInfoDao.updateShareOrderStatus(paramMap);
			//分享维度的订单销售数据更新(更新每个分享的最新订单销售数据)
			List<Map<String, Object>> shareStatisticsList = shareInfoDao.listShareOrderStatistics(paramMap);
			if (shareStatisticsList.size() >0) {			
				shareInteractionCountDao.batchUpdate(shareStatisticsList);
			}
			
			//分享商品维度的销售数据查询<productId, 商品销售数据>
			Map<Long ,Map<String, Object>> productStatisticsMap = shareInfoDao.listShareProductStatistics(paramMap);
			//统计分享与PV中的key总数
			Set<String> dailyShareKeys = new HashSet<String>();
			dailyShareKeys.addAll(redisCacheClient.getHashKeys(DAILY_SHARE_QUANTITY));
			dailyShareKeys.addAll(redisCacheClient.getHashKeys(DAILY_SHARE_PV_VIEW));
			List<ShareProductStatisticsEntity> dailyStatisticsList = new ArrayList<ShareProductStatisticsEntity>();
			for (String key : dailyShareKeys) {
				Long productId = Long.parseLong(key);
				//组装日常统计实体
				ShareProductStatisticsEntity dailyEntity = new ShareProductStatisticsEntity();
				dailyEntity.setProductId(productId);
				dailyEntity.setShareQuantity(redisCacheClient.getHashValue(DAILY_SHARE_QUANTITY, key));
				dailyEntity.setPvViewQuantity(redisCacheClient.getHashValue(DAILY_SHARE_PV_VIEW, key));
				dailyEntity.setUvViewQuantity(redisCacheClient.getHashValue(DAILY_SHARE_UV_VIEW, key));
				dailyEntity.setRegisterQuantity(redisCacheClient.getHashValue(DAILY_SHARE_REGISTER, key));
				if (productStatisticsMap.containsKey(productId)) {
					Long orderNum = Long.parseLong(productStatisticsMap.get(productId).get("orderNum").toString());
					String totalOrderMoney = productStatisticsMap.get(productId).get("totalOrderMoney").toString();
					dailyEntity.setShareOrderNum(orderNum);
					dailyEntity.setShareTotalMoney(new BigDecimal(totalOrderMoney));
					productStatisticsMap.remove(productId);
				} else {
					dailyEntity.setShareOrderNum(0L);
					dailyEntity.setShareTotalMoney(new BigDecimal(0));
				}
				//定时器是00:10分启动,因为是统计昨日数据,隐藏修改时间为昨日23:59:59
				dailyEntity.setModifyTime(DateUtils_add.getDayEnd(cal.getTime()));
				dailyStatisticsList.add(dailyEntity);
			}
			//如果仍有销售数据未被统计,则继续统计剩余销售数据的每日信息
			for (Map.Entry<Long , Map<String, Object>> entry : productStatisticsMap.entrySet()) {
				Long productId = entry.getKey();
				Map<String, Object> entity = entry.getValue();
				//组装日常统计实体
				ShareProductStatisticsEntity dailyEntity = new ShareProductStatisticsEntity();
				dailyEntity.setProductId(productId);
				dailyEntity.setShareQuantity(0L);
				dailyEntity.setPvViewQuantity(0L);
				dailyEntity.setUvViewQuantity(0L);
				dailyEntity.setRegisterQuantity(0L);
				Long orderNum = Long.parseLong(entity.get("orderNum").toString());
				String totalOrderMoney = entity.get("totalOrderMoney").toString();
				dailyEntity.setShareOrderNum(orderNum);
				dailyEntity.setShareTotalMoney(new BigDecimal(totalOrderMoney));
				//定时器是00:10分启动,因为是统计昨日数据,隐藏修改时间为昨日23:59:59
				dailyEntity.setModifyTime(DateUtils_add.getDayEnd(cal.getTime()));
				dailyStatisticsList.add(dailyEntity);
			}
			
			if (dailyStatisticsList.size() > 0) {
				//更新分享商品每日销售数据
				shareProductStatisticsDao.batchInsertDailyStatistics(dailyStatisticsList);
				//更新分享商品总销售数据(每日数据叠加至旧数据上)
				shareProductStatisticsDao.batchUpdate(dailyStatisticsList);
				//删除本日redis统计数据(模糊匹配DAILY_SHARE_*)
				redisCacheClient.evictBatchKeys("DAILY_SHARE_");
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new BizException("分享销售数据统计失败！");
		}
		return 1;
	}

	/**
	 * 分享商品的分享数+1
	 * @param productId
	 * @return
	 * @author xkl
	 * @date 2018年6月9日 下午2:48:14
	 */
	@Override
	public Long doShareProductRecord(Long productId) {
		return redisCacheClient.doHashIncrby(DAILY_SHARE_QUANTITY, productId.toString());
	}

	/**
	 * 分享商品的注册引导次数+1
	 * @param productId
	 * @return
	 * @author xkl
	 * @date 2018年6月9日 下午2:48:45
	 */
	@Override
	public Long doShareProductRegister(Long productId) {
		return redisCacheClient.doHashIncrby(DAILY_SHARE_REGISTER, productId.toString());
	}

	/**
	 * 分享商品的PV、UV统计
	 * @param productId
	 * @param customer
	 * @return
	 * @author xkl
	 * @date 2018年6月9日 下午2:48:54
	 */
	@Override
	public Long doShareProductPVUV(Long productId, String customer) {
		//分享商品浏览数+1(PV)
		redisCacheClient.doHashIncrby(DAILY_SHARE_PV_VIEW, productId.toString());
		
		//检查用户是否查看过该分享商品(UV)
		Long isUserView = redisCacheClient.getHashValue(DAILY_SHARE_UV_VIEW_USER, productId + "_" + customer);
		if (isUserView <= 0) {
			//分享商品UV+1
			redisCacheClient.doHashIncrby(DAILY_SHARE_UV_VIEW, productId.toString());
			//记录查看的用户
			redisCacheClient.doHashIncrby(DAILY_SHARE_UV_VIEW_USER, productId + "_" + customer);
		}
		return 1L;
	}

	/**
	 * 保存访问用户推荐人
	 * @param sessionId
	 * @param invitationCode
	 * @author xkl
	 * @date 2018年6月26日 下午4:01:25
	 */
	@Override
	public boolean doRecordInvitation(String sessionId, String invitationCode) {
		logger.debug("会话ID:" + sessionId + " 推荐码:"+ invitationCode);
		boolean isOk = redisCacheClient.doSet(INVITE+sessionId, invitationCode);
		if (isOk) {
			redisCacheClient.doExpire(INVITE+sessionId, 7200);
		}
		return isOk;
	}

	/**
	 * 获取用户邀请人的邀请码
	 * @param sessionId
	 * @return
	 * @author xkl
	 * @date 2018年6月26日 下午5:12:58
	 */
	@Override
	public String getParentInvitationCode(String sessionId) {
		return redisCacheClient.doGet(INVITE+sessionId);
	}

	/**
	 * 保存模块分享记录
	 * @param shareModule
	 * @param shareInfoList
	 * @return
	 * @author xkl
	 * @date 2018年7月4日 下午1:41:18
	 */
	@Override
	@Transactional
	public int saveShareModuleList(ShareInfoEntity shareModule, List<ShareInfoEntity> shareInfoList) {
		try {
			//保存模块记录
			Long shareModuleId = shareInfoDao.insert(shareModule);
			//保存模块下子商品记录
			List<ShareInteractionCountEntity> interactionList = new ArrayList<ShareInteractionCountEntity>();
			List<ShareProductStatisticsEntity> statisticsList = new ArrayList<ShareProductStatisticsEntity>();
			//初始化子记录分享几商品统计记录
			for (ShareInfoEntity entity : shareInfoList) {
				entity.setSharedModuleId(shareModuleId);
				Long shareId = shareInfoDao.insert(entity);
				entity.setId(shareId);
				
				//初始化分享统计及商品统计
				interactionList.add(initShareInteraction(entity));
				//初始化商品统计数据(若存在则不需要初始化)
				int count = shareProductStatisticsDao.isExistsProductStatistics(entity.getSharedProductId());
				if (count == 0 && SHARE_TYPE.PRODUCT.getCode().equals(entity.getShareType())) {
					statisticsList.add(initShareStatistics(entity));
				}
			}
			shareInteractionCountDao.insert(interactionList);
			shareProductStatisticsDao.insert(statisticsList);
		} catch (Exception e) {
			e.printStackTrace();
			throw new BizException("分享销售数据统计失败！");
		}
		return 1;
	}
	
	/**
	 * 初始化新分享的分享交互统计数据
	 * @param shareInfo
	 * @return
	 * @author xkl
	 * @date 2018年7月4日 下午1:49:42
	 */
	protected ShareInteractionCountEntity initShareInteraction(ShareInfoEntity shareInfo){
		//初始化分享交互统计数据
		ShareInteractionCountEntity interactionEntity = new ShareInteractionCountEntity();
		interactionEntity.setId(shareInfo.getId());
		interactionEntity.setShareLikeQuantity(0L);
		interactionEntity.setShareCommentQuantity(0L);
		interactionEntity.setFavoriteQuantity(0L);
		interactionEntity.setShareQuantity(0L);
		interactionEntity.setViewQuantity(0L);
		interactionEntity.setRegisterQuantity(0L);
		interactionEntity.setUvViewQuantity(0L);
		interactionEntity.setShareOrderNum(0L);
		interactionEntity.setShareTotalMoney(new BigDecimal("0.00"));
		return interactionEntity;
	}
	
	/**
	 * 初始化新分享的商品统计数据
	 * @param shareInfo
	 * @return
	 * @author xkl
	 * @date 2018年7月4日 下午1:51:26
	 */
	protected ShareProductStatisticsEntity initShareStatistics(ShareInfoEntity shareInfo) {
		//初始化分享商品统计数据
		ShareProductStatisticsEntity statisticsEntity = new ShareProductStatisticsEntity();
		statisticsEntity.setProductId(shareInfo.getSharedProductId());
		statisticsEntity.setProductName(shareInfo.getShareTitle());
		statisticsEntity.setProductCode(shareInfo.getProductCode());
		statisticsEntity.setProductCategoryName(shareInfo.getProductCategoryName());
		statisticsEntity.setProductImagePath(shareInfo.getSharedProductImagePath());
		statisticsEntity.setShareQuantity(0L);
		statisticsEntity.setPvViewQuantity(0L);
		statisticsEntity.setUvViewQuantity(0L);
		statisticsEntity.setRegisterQuantity(0L);
		statisticsEntity.setShareOrderNum(0L);
		statisticsEntity.setShareTotalMoney(new BigDecimal("0.00"));
		return statisticsEntity;
	}
}
